package roby.publicEncryption;

import java.util.ArrayList;

public class CyclicGroup {

	private static int[] group;
	private static int primeNumber;
	private static ArrayList<Integer> generators;
	
	private static boolean isPrime(int n){
		// 2 is the smallest prime
	    
        if (n <= 2) {
            return n == 2;
        }

        // even numbers other than 2 are not prime

        if (n % 2 == 0) {
            return false;
        }

        // check odd divisors from 3
        // to the square root of n

        for (int i = 3, end = (int)Math.sqrt(n);
        i <= end; i += 2) {
            if (n % i == 0) {
                return false;
            }
        }

        return true;
	}
	// find the smallest prime >= n
    
    private static int getPrime(int n) {
        while (!isPrime(n)) {
            n++;
        }
        return n;
    }
    
    private static void generateGroup(){
    	primeNumber = getPrime(1073741824);
    	group = new int[primeNumber-1];
    	for(int i = 0; i < primeNumber; i++){
    		group[i] = i;
    	}
    }
    
    public static void prepareGenerators(){
    	generateGroup();
    	generators = new ArrayList<Integer>();
    	for(int i = 0; i < group.length; i++){
    		boolean generator = true;
    		boolean[] elements = new boolean[group.length];
    		for(int j = 0; j < group.length; j++)
    			elements[j] = false;
    		for(int j = 1; j < primeNumber; j++){
    			int temp = (int) Math.pow(group[i], j) % primeNumber;
    			for(int k = 0; k < group.length; k++){
    				if(group[k] == temp){
    					if(elements[k] == true){
    						break;
    					}
    					else
    						elements[k] = true;
    				}
    			}
    		}
    		for(int k = 0; k < group.length; k++){
				if(elements[k] == false)
					generator = false;
			}
    		if(generator)
    			generators.add(group[i]);
    	}
    }

    public static int getGenerator(){
    	int index = (int) (Math.random() * generators.size());
    	return generators.get(index);
    }
    
	public static int getPrimeNumber() {
		return primeNumber;
	}

	
}
